package com.donger.auth.filter;

import cn.hutool.core.util.StrUtil;
import com.donger.auth.config.CaptchaProperties;
import com.donger.auth.exception.ValidateCodeException;
import com.donger.auth.handler.ValidateCodeType;
import com.donger.auth.utils.MyRequestWrapper;
import com.donger.auth.validate.BuildValidateCodeProcessor;
import com.donger.common.core.constant.SecurityConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 主过滤器，在OAuth之前执行
 * <p>
 * 主要是过滤出  图片验证码   和   短信验证码
 */
@Component
@Slf4j
public class ValidateCodeFilter extends OncePerRequestFilter {

    @Autowired
    private AuthenticationFailureHandler authenticationFailureHandler;

    @Autowired
    private CaptchaProperties captchaProperties;

    @Autowired
    private BuildValidateCodeProcessor buildValidateCodeProcessor;


    /**
     * 过滤器主体，首先判断请求的验证码是否正确，包含图片验证码 短信验证码
     * <p>
     * 请求过滤器
     *
     * @param req
     * @param res
     * @param filterChain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) throws IOException, ServletException {
        String requestUrl = req.getServletPath();
        PathMatcher pathMatcher = new AntPathMatcher();
        try {
            // 判断图片验证码
            for (String url : captchaProperties.getImage()) {
                if (pathMatcher.match(url, requestUrl)) {
                    buildValidateCodeProcessor.build(ValidateCodeType.IMAGE).validate(req);
                    break;
                }
            }
            // 判断 手机号验证码
            for (String url : captchaProperties.getSms()) {
                if (pathMatcher.match(url, requestUrl)) {
                    buildValidateCodeProcessor.build(ValidateCodeType.SMS).validate(req);
                    break;
                }
            }
        } catch (ValidateCodeException e) {
            log.error(e.getLocalizedMessage());
            authenticationFailureHandler.onAuthenticationFailure(req, res, e);
            return;
        }


        String encry = req.getHeader("encry");
        // 图片验证码的进行密码加密 即 /oauth/token  中进行解密
        if (SecurityConstants.DEFAULT_PARAMETER_CODE_IMAGE_URL.equals(requestUrl) && StrUtil.isNotEmpty(encry) && encry.equals("1")) {
            MyRequestWrapper myRequestWrapper = new MyRequestWrapper(req);
            filterChain.doFilter(myRequestWrapper, res);
            return;
        }

        /**
         * 本过滤器结束
         */
        filterChain.doFilter(req, res);
    }
}
